﻿using LibraryProject.Model;
using LibraryProject.Service;
using MauiProject.Model.LinkFilePageModel;
using MauiProject.Tool;
using System.Text.Json;
namespace MauiProject.Pages;

using BootstrapBlazor.Components;
using LibraryProject.Service.Implement;
using System.Collections.Generic;

public partial class LinkFilePage {
    private ILinkFileService _linkFileService;
    private IAccountService _accountService;
    private IMongodbService _mongodbService;

    // 当前登录用户的信息存储
    private Account Account { get; set; } = new Account() { AccountId = "00000000" };
    // 当前登录用户的目录信息
    private List<TreeItem> TreeItems { get; set; } = new List<TreeItem>();
    // 侧边栏相关变量
    private DrawComponent DrawComponent { get; set; } = new DrawComponent();
    // 当前点击的树节点
    private TreeItem CurrentTreeItem { get; set; } = new TreeItem();
    // 添加的树节点
    private TreeItem NewTreeItem { get; set; } = new TreeItem();
    // 循环遍历树的标志
    private bool ForTreeItemFlag { get; set; } = true;
    // 初始化定时器，用来记录用户点击目录树的鼠标停留事件，判断是否为长按事件
    private System.Timers.Timer Timer { get; set; }
    private bool AddRootDirFlag { get; set; }
    private string AddRootDirName { get; set; } = "";


    protected override async Task OnInitializedAsync() {
        // 初始化服务
        _linkFileService = new LinkFileService();
        _accountService = new AccountService();
        _mongodbService = new MongodbService();

        // 初始化定时器
        InitTimer();
        // 初始化账号信息
        await InitAccountInfo();
        // 初始化目录信息
        await InitTreeItems();

        await base.OnInitializedAsync();
    }

    // 初始化定时器
    private void InitTimer() {
        Timer = new System.Timers.Timer(1000) {
            AutoReset = false
        };
        Timer.Elapsed += (_, _) => {
            DrawComponent.DrawOpenControl = true;
            /*InvokeAsync(StateHasChanged);*/
        };
    }

    // 侧边栏展开事件
    // 如果点击的是文件夹，则展开侧边栏
    // 如果点击的是文件，则打开文件
    private Task OnTreeItemClick(TreeItem item) {
        // 侧边栏的控制权交给了OnMouseDown()和Timer的事件
        // OnMouseDown()开启定时器， Timer在1.5s后的事件触发侧边栏的展开

        // 判断是否是长按事件，如果是长按事件，则对侧边栏进行操作（数据显示）
        if (DrawComponent.DrawOpenControl) {
            // 如果是链接，不允许使用添加菜单; 如果是文件夹，允许使用添加菜单
            DrawComponent.DrawMenuItems.ToList()[1].IsDisabled = !item.HasChildNode;
            //侧边栏表单初始数据填充 
            CurrentTreeItem = item;
            DrawComponent.DrawFormData.CurrentDic = item.Text;
            StateHasChanged();
        } else {
            // 如果点击的是文件夹，则不做任何处理
            if (item.HasChildNode) return Task.CompletedTask;
            // 如果点击的是文件，则打开文件
            // TODO: 打开文件
        }

        return Task.CompletedTask;
    }

    // 侧边栏菜单按钮点击事件
    // 选择操作的模式
    private async Task OnClickMenu(MenuItem item) {
        switch (item.Text) {
            case null:
                break;
            case "添加":
                DrawComponent.DrawFormAbleControl.AddMode();
                break;
            case "重命名":
                DrawComponent.DrawFormAbleControl.RenameMode();
                break;
            case "删除":
                DrawComponent.DrawFormAbleControl.DeleteMode();
                // TODO: 删除文件夹
                await BeforeAction();
                await DeleteLinkFile();
                await AfterAction();
                break;
        }
        StateHasChanged();
    }

    // 侧边栏表单按钮点击事件
    private async Task Submit() {
        // 在操作时，先判断是否与云端数据同步
        try {
            await BeforeAction();
            switch (DrawComponent.DrawFormAbleControl.CurrentModeId) {
                case "0": // 添加文件夹
                    await RenameLinkFile();
                    break;
                case "1": // 重命名文件夹
                    await AddLinkFile();
                    break;
                case "2": // 删除文件夹
                    break;
            }
            await AfterAction();
            await OnCloseDraw();
            await ShowMessageInfo("操作成功", 1);
        } catch (Exception) {
            await ShowMessageInfo("操作失败", 0);
            throw;
        }

    }

    // 添加操作
    private async Task AddLinkFile() {
        // 初始化添加的文件信息
        var newLinkFile = new LinkFile() {
            Name = DrawComponent.DrawFormData.Name,
            IsDir = DrawComponent.SelectedValue == "1" ? 1 : 0,
            ParentId = CurrentTreeItem.Id == null ? -1 : int.Parse(CurrentTreeItem.Id),
        };

        // 添加文件信息到数据库, 添加成功后，id自动赋值到newLinkFile
        await _linkFileService.InsertOne(newLinkFile);

        // 添加文件信息到树结构中
        NewTreeItem = LinkFilePageTool.ConvertLinkFileToTreeItem(newLinkFile);
        // 遍历树结构
        var rootTreeItem = new TreeItem() {
            Items = TreeItems
        };
        ForTreeItem(rootTreeItem);
        ForTreeItemFlag = true;
    }

    // 重命名操作
    private async Task RenameLinkFile() {
        if (CurrentTreeItem.Id != null && CurrentTreeItem.Text != null) {
            // 修改数据库中的name
            await _linkFileService.UpdateName(
    new LinkFile() {
        Id = int.Parse(CurrentTreeItem.Id),
        Name = DrawComponent.DrawFormData.CurrentDic,
    });

            // 遍历树结构
            var rootTreeItem = new TreeItem() {
                Items = TreeItems
            };
            ForTreeItem(rootTreeItem);
            ForTreeItemFlag = true;
        }
    }

    // 删除操作
    private async Task DeleteLinkFile() {
        if (CurrentTreeItem.Id != null) {
            // 删除数据库中的数据
            await _linkFileService.DeleteById(int.Parse(CurrentTreeItem.Id));

            // 遍历树结构
            var rootTreeItem = new TreeItem() {
                Id = "0",
                Items = TreeItems
            };
            ForTreeItem(rootTreeItem);
            ForTreeItemFlag = true;
        }
    }

    private void ForTreeItem(TreeItem tree) {
        if (tree == null || !ForTreeItemFlag) return;

        switch (DrawComponent.DrawFormAbleControl.CurrentModeId) {
            case "1": {
                    // 执行添加操作
                    if (tree.Id == NewTreeItem.ParentId) {// 如果找到了父节点，则添加到父节点的子节点中，并停止遍历
                        tree.Items.Add(NewTreeItem);
                        ForTreeItemFlag = false;
                    }

                    break;
                }
            case "0": {
                    // 执行rename操作
                    if (tree.Id == CurrentTreeItem.Id) {
                        tree.Text = DrawComponent.DrawFormData.CurrentDic;
                        ForTreeItemFlag = false;
                    }

                    break;
                }
            case "2": {
                    // 执行delete操作
                    if (tree.Id == CurrentTreeItem.ParentId) {
                        tree.Items.Remove(CurrentTreeItem);
                        ForTreeItemFlag = false;
                    }

                    break;
                }
        }
        // 如果当前节点有子节点，则遍历子节点
        foreach (var item in tree.Items) {
            ForTreeItem(item);
        }
    }

    // 初始化目录信息
    private async Task InitTreeItems() {
        // 从数据库读取目录信息，并组成树结构
        var linkFiles = await _linkFileService.QueryAll();
        var rootTreeItem = LinkFilePageTool.SorTreeItem(linkFiles);
        //将一级目录放入TreeItems中
        rootTreeItem.Items.ForEach(item => TreeItems.Add(item));
    }

    // 初始化账号信息
    private async Task InitAccountInfo() {
        // 1. 创建account表（检查表是否存在）
        var tableResult = await _accountService.CreateTable();

        // 2. 判断表是否存在
        if (tableResult == 1) { // 表是新创建的，则初始化表
                                // TODO： 通过前端获取用户的账号
                                // 访问mongodb数据库，查看是否存在账号
            var mongodbAccount = await _mongodbService.QueryByAccountId(Account.AccountId);

            if (mongodbAccount == null) {// 如果不存在账号，则初始化账号
                await _mongodbService.AddAccount(Account.AccountId); // 向mongodb数据库添加账号
                Account.DeviceId = "0"; // 为当前设备赋予设备id
                await _accountService.InitTable(Account.AccountId, Account.DeviceId); // 初始化account表
                await _linkFileService.InitDb(); // 初始化LinkFile表
            } else { //如果存在账号，获取count值，为当前设备赋予设备id，同时初始化LinkFile表
                     // 为当前设备赋予设备id,并初始化account表
                Account.DeviceId = (mongodbAccount.Count + 1).ToString();
                await _accountService.InitTable(Account.AccountId, Account.DeviceId);
                // 从mongodb数据库读取data数据
                var linkFiles = JsonSerializer.Deserialize<List<LinkFile>>(mongodbAccount.Data);
                // 将读取的data覆盖到本地数据库
                await _linkFileService.CreateTable();
                await _linkFileService.InsertAll(linkFiles);
                // 将mongodb数据库的count自增
                await _mongodbService.IncrementDeviceCount(mongodbAccount.AccountId, mongodbAccount.Count);
            }
        } else { // 表存在，说明account和deviceId存在，直接读取
            Account = await _accountService.QueryData();
        }
    }

    // 判断是否与云端数据同步
    private async Task BeforeAction() {
        // 获取云端数据
        var mongodbAccount =
            await _mongodbService.QueryByAccountId(Account.AccountId);

        if (mongodbAccount == null) return;

        // 比较云端的操作者和本地的操作者是否一致
        if (mongodbAccount.Operator == Account.DeviceId) return;

        // 如果不一致，则进行本地LinkFile表覆盖操作
        var linkFiles = JsonSerializer
            .Deserialize<List<LinkFile>>(mongodbAccount.Data);
        // 删除本地LinkFile表
        await _linkFileService.DeleteTable();
        // 重新创建本地LinkFile表
        await _linkFileService.CreateTable();
        // 将云端的数据插入到本地LinkFile表
        await _linkFileService.InsertAll(linkFiles);
        // 修改mongodb数据库的operator
        await _mongodbService.UpdateOperatorByAccountId(
            Account.AccountId, int.Parse(Account.DeviceId));
        // 重新初始化目录信息
        TreeItems.Clear();
        await InitTreeItems();
    }

    // 在操作结束后，将本地数据同步到云端
    public async Task AfterAction() {
        // 获取本地数据
        var linkFiles = await _linkFileService.QueryAll();
        // 将本地数据转换为json格式
        var data = JsonSerializer.Serialize(linkFiles);
        // 将数据同步到云端
        await _mongodbService.UpdateAttrByAccountId(Account.AccountId, "data", data);
    }

    // 鼠标点击事件
    public void OnMouseDown() {
        DrawComponent.DrawOpenControl = false;
        Timer.Start();
    }

    // 鼠标松开事件
    public void OnMouseUp() {
        Timer.Stop();
    }

    // 侧边栏关闭事件,点击侧栏旁边遮罩层时触发
    public Task OnCloseDraw() {
        // 关闭侧边栏
        DrawComponent.DrawOpenControl = false;
        // 重置表单
        DrawComponent.DrawFormAbleControl.RenameMode();
        DrawComponent.DrawMenuItems.ToList()[0].IsActive = true;
        DrawComponent.DrawMenuItems.ToList()[1].IsActive = false;
        // DrawComponent.DrawMenuItems.ToList()[2].IsActive = false;
        return Task.CompletedTask;
    }

    // 删除确认框的确认按钮点击事件
    public async Task DeleteConfirm() {
        DrawComponent.DrawFormAbleControl.DeleteMode();
        await BeforeAction();
        await DeleteLinkFile();
        await AfterAction();
        await OnCloseDraw();
        await ShowMessageInfo("删除成功", 1);
        StateHasChanged();
    }

    // 消息提示框函数，0为错误提示，1为成功提示, 2为普通提示
    public async Task ShowMessageInfo(string text, int mode) {
        switch (mode) {
            case 0:
                await MessageService.Show(DrawComponent.MyMessageOption.GetErrorOption(text));
                break;
            case 1:
                await MessageService.Show(DrawComponent.MyMessageOption.GetSuccessOption(text));
                break;
            case 2:
                await MessageService.Show(DrawComponent.MyMessageOption.GetSecondaryOption(text));
                break;
        }
    }

    // 添加根目录
    public async Task AddRootDir() {
        try {
            await BeforeAction();

            // 将添加的根目录信息添加到数据库
            var linkFile = new LinkFile() {
                Name = AddRootDirName,
                IsDir = 1,
                ParentId = 0,
            };
            await _linkFileService.InsertOne(linkFile);
            // 将添加的根目录信息添加到树结构中
            var newTreeItem = LinkFilePageTool.ConvertLinkFileToTreeItem(linkFile);
            TreeItems.Add(newTreeItem);

            await AfterAction();

            AddRootDirFlag = false;
            AddRootDirName = "";
            await ShowMessageInfo("添加成功", 1);
        } catch (Exception) {
            await ShowMessageInfo("添加失败", 0);
        }

    }
}